
// let timeStamp = null;

// function getTimeStamp() {
//   console.log(1)
//   if (timeStamp) {
//     return timeStamp;
//   }
//   console.log(2)
//   timeStamp = Date.now();
//   return timeStamp;
// }

// 问题：
// 1. 全局污染
// 2. 重复检查、判断，



/**
 * 函数重写
 * 
 * 由于一个函数可以返回另一个函数，因此可以用新的函数来覆盖旧的函数
 * 
 */

// function a(){
//   console.log('a');
//   a = function(){
//     console.log('b');
//   }
// }

// a(); // a
// a(); // b
// a(); // b
// a(); // b

// 第一次调用该函数时会console.log('a')会被执行, 全局变量a被重定义，并被赋予新的函数。
// 当该函数再次被调用时，console.log('b')会被执行




/**
 * 惰性函数 Lazy Function (闭包函数的一种)
 * 
 * 针对优化频繁使用的函数。常用于函数库的编写、单例模式之中
 * 
 * 1. 惰性载入表示函数执行的分支只会在函数第一次调用的时候执行
 * 2. 在第一次调用过程中，该函数会被覆盖为另一个按照合适方式执行的函数，
 * 3. 这样任何对原函数的调用就不用再经过执行的分支了。
 * 
 * 本质就是函数重写
 */


// 方法一：
// let getTimeStamp = (function () {
//   console.log(1)
//   let timeStamp = Date.now();

//   return function() {
//     console.log(2);
//     return timeStamp;
//   };
// })();

// console.log(getTimeStamp());
// console.log(getTimeStamp());
// console.log(getTimeStamp());
// console.log(getTimeStamp());

// // 问题： 并不是每次执行都拿到的第一次执行的结果

// 立即执行函数只执行一次 在变量提升、预编译时就已经执行，执行完返回一个函数，
// 函数返回一个值，之后不管多少次调用也是得到这个返回值


// 方法二：
// let getTimeStamp = function () {
//   let timeStamp = Date.now();
//   console.log(1);

//   getTimeStamp = function () {
//     console.log(2);
//     return timeStamp;
//   }

//   return timeStamp;
// }

// 问题：return了两次一样的值

// 改进
let getTimeStamp = function () {
  let timeStamp = Date.now();
  console.log(1);

  getTimeStamp = function () {
    console.log(2);
    return timeStamp;
  }

  return getTimeStamp();
}

// 缺点： 如果函数名称有所改变，修改起来比较麻烦

console.log(getTimeStamp());
console.log(getTimeStamp());
console.log(getTimeStamp());
console.log(getTimeStamp());



// 使用switch 判断
function test(num) {
  switch (num) {
    case 1:
      test = function () {
        console.log(11111);
      }
      break;
    case 2:
      test = function () {
        console.log(22222);
      }
      break;
    case 3:
      test = function () {
        console.log(33333);
      }
      break;
    default:
      break;
  }
  return test();
}
test(3);
test(2);
test(3);
test(1);




// 例一：柯里化绑定函数
// var addEvent = (function() {
//   if (window.addEventListener) {
//     return function(el, type, fn, capture) {
//       el.addEventListener(type, fn, capture);
//     }

//   } else if (window.attachEvent) {
//     return function(el, type, fn) {
//       el.attachEvent('on' + type, function () {
//         // 如果直接传fn，this会指向window
//         fn.call(el);
//       })
//     }
 
//   } else {
//     return function(el, type, fn) {
//       el['on' + type] = fn;
//     }
//   }
// })();


// 例二：惰性包裹
var addEvent = function (el, type, fn, capture) {
  if (el.addEventListener) {
    addEvent = function (el, type, fn, capture) {
      el.addEventListener(type, fn, capture);
    }
  } else if (el.attachEvent) {
    addEvent = function (el, type, fn) {
      el.attachEvent('on' + type, function () {
        fn.call(el);
      })
    }
  } else {
    addEvent = function (el, type, fn) {
      el['on' + type] = fn;
    }
  }

  addEvent(el, type, fn, capture);
}
